package at.fhj.antesk.steamvaluecalc;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import at.fhj.antesk.steamvaluecalc.interfaces.Retriever;

public class MainFrame {

	private Retriever retriever = new GameDataRetriever();
	private List<Game> gameList;
	private String[] columnNames;
	private Map<String, String> configsMap;
	private String account;
	private String windowTitle;
	private boolean hasNoAlias;

	private JFrame frame = new JFrame();
	private JTable mainTable;
	private JScrollPane scrollPane;
	private JMenuBar menuBar;
	private JMenu file;
	private JMenu gameListOptions;
	private JMenuItem exitItem;
	private JMenuItem loadGameList;
	private JMenuItem changeAccount;
	private JMenuItem loadPrices;
	private JProgressBar progress;

	private static Logger logger = LoggerFactory.getLogger(MainFrame.class);

	public MainFrame() {
		configsMap = retriever.getConfigsMap();
		account = configsMap.get("account");
		windowTitle = configsMap.get("window.title");
		columnNames = retriever.getCsvMap().get("table.headers");

		retriever.setMainFrame(this);

		try {
			UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
		} catch (Exception e) {
			logger.error("Look and Feel could not be loaded", e);
		}

		createFrameProperties();
		drawTable();
		drawProgressBar();
		drawMenuBar();

		frame.validate();
	}

	private void createFrameProperties() {
		frame.setSize(800, 600);
		frame.setLocationRelativeTo(null);
		frame.setTitle(windowTitle + " - Account: " + account);
		frame.getContentPane().setLayout(new BorderLayout());
		frame.setVisible(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	private void drawTable() {
		if (scrollPane != null) {
			frame.getContentPane().remove(scrollPane);
		}

		gameList = retriever.retrieveGameListForAccount(account);

		String[][] gameListArrayForTable = retriever.createGameListArrayForTable(gameList);

		if (progress != null) {
			progress.setMaximum(gameList.size());
			progress.setValue(0);
		}

		mainTable = new JTable(gameListArrayForTable, columnNames);
		mainTable.getColumnModel().getColumn(0).setPreferredWidth(240);
		mainTable.getColumnModel().getColumn(1).setPreferredWidth(200);
		scrollPane = new JScrollPane(mainTable);
		frame.getContentPane().add(scrollPane);
		frame.setTitle(windowTitle + " - Account: " + account);
		frame.validate();
	}

	private void drawMenuBar() {
		menuBar = new JMenuBar();
		file = new JMenu("File");
		gameListOptions = new JMenu("Game List");
		menuBar.add(file);
		menuBar.add(gameListOptions);

		exitItem = new JMenuItem("Exit");
		exitItem.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				System.exit(0);
			}
		});

		loadGameList = new JMenuItem("Reload Game List");
		loadGameList.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				drawTable();
			}
		});

		changeAccount = new JMenuItem("Change Account");
		changeAccount.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				try {
					String changedAccount = JOptionPane.showInputDialog(null, "Enter account name or profile ID:",
							"Change Account", JOptionPane.QUESTION_MESSAGE, null, null, account).toString();

					// TODO confirmation that all profile ids start with this number
					String prefix = "765611979";
					if (changedAccount.startsWith(prefix)) {
						System.out.println("Is Id.");
						hasNoAlias = true;
					} else {
						hasNoAlias = false;
					}

					if (!changedAccount.equals(account)) {
						account = changedAccount;
						logger.debug("Loading game list for account: " + account);
						drawTable();
					}
				} catch (NullPointerException e) {
					logger.debug("Silent catch for NullPointerException in " + arg0.getActionCommand()
							+ ". Name was not changed.", e);
				}
			}
		});

		loadPrices = new JMenuItem("Get Prices");
		loadPrices.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {

				Runnable retrievePrices = new Runnable() {

					@Override
					public void run() {
						try {
							retriever.retrievePricedGameListWithProgressBar(gameList, progress, mainTable);
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				};

				Thread thread = new Thread(retrievePrices);
				thread.start();
			}
		});

		file.add(exitItem);

		gameListOptions.add(loadGameList);
		gameListOptions.add(changeAccount);
		gameListOptions.add(loadPrices);

		frame.setJMenuBar(menuBar);
	}

	private void drawProgressBar() {
		progress = new JProgressBar();
		progress.setMinimum(0);
		progress.setMaximum(gameList.size());
		frame.getContentPane().add(progress, BorderLayout.PAGE_END);
	}

	public boolean hasNoAlias() {
		return hasNoAlias;
	}

}